﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;

namespace System
{
    /// <summary>
    /// 特性辅助类
    /// </summary>
    public static class AttributeHelper
    {
        #region Methods

        /// <summary>
        ///  获取自定义Attribute
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <typeparam name="A">泛型</typeparam>
        /// <returns>未获取到则返回NULL</returns>
        public static A Get<T, A>()  where T : class  where A : System.Attribute
        {
            var modelType = typeof(T);
            var modelAttrs = modelType.GetCustomAttributes(typeof(A), true);
            bool? any = false;
            foreach (var dummy in modelAttrs)
            {
                any = true;
                break;
            }
            return (bool)any ? modelAttrs.FirstOrDefault() as A : null;
        }
        public static A Get<A>(Type type) where A : System.Attribute
        {
            var modelAttrs = type.GetCustomAttributes(typeof(A), true);
            bool? any = false;
            foreach (var dummy in modelAttrs)
            {
                any = true;
                break;
            }
            return (bool)any ? modelAttrs.FirstOrDefault() as A : null;
        }
        public static A Get<A>(PropertyInfo type) where A : System.Attribute
        {
            var modelAttrs = type.GetCustomAttributes(typeof(A), true);
            bool? any = false;
            foreach (var dummy in modelAttrs)
            {
                any = true;
                break;
            }
            return (bool)any ? modelAttrs.FirstOrDefault() as A : null;
        }
        public static A Get<A>(FieldInfo type) where A : System.Attribute
        {
            var modelAttrs = type.GetCustomAttributes(typeof(A), true);
            bool? any = false;
            foreach (var dummy in modelAttrs)
            {
                any = true;
                break;
            }
            return (bool)any ? modelAttrs.FirstOrDefault() as A : null;
        }
        public static string GetDescription(PropertyInfo field)
        {
            string result = string.Empty;
            var dbKey = (DescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
            if (dbKey != null) result = dbKey.Description;
            return result;
        }
        public static string GetClassDescription(MemberInfo field)
        {
            string result = string.Empty;
            var dbKey = (DescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
            if (dbKey != null) result = dbKey.Description;
            return result;
        }
        /// <summary>
        /// 检查givenType是否继承genericType
        /// </summary>
        public static bool IsAssignableToGenericType(Type givenType, Type genericType)
        {
            var givenTypeInfo = givenType.GetTypeInfo();

            if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
            {
                return true;
            }
            foreach (var interfaceType in givenType.GetInterfaces())
            {
                if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType)
                {
                    return true;
                }
            }
            if (givenTypeInfo.BaseType == null)
            {
                return false;
            }
            return IsAssignableToGenericType(givenTypeInfo.BaseType, genericType);
        }
        /// <summary>
        ///  Console.WriteLine(GetPropertyName<class>(u=>u.Name1));
        /// </summary>
        public static string GetPropertyName<T>(Expression<Func<T, string>> expr)
        {
            var name = ((MemberExpression)expr.Body).Member.Name;
            return name;
        }
        #endregion Methods
    }
}
